package com.zj.docker.service.impl;

import com.google.common.collect.ImmutableSet;
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.Image;
import com.spotify.docker.client.messages.ImageInfo;
import com.zj.docker.Repository.ImagesInfoRepository;
import com.zj.docker.common.MqTask;
import com.zj.docker.component.DockerComponent;
import com.zj.docker.domain.ImagesInfo;
import com.zj.docker.rabbitmq.Sender;
import com.zj.docker.service.ImagesInfoService;
import com.zj.docker.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.List;

/**
 * @Auther: zj
 * @Date: 2018/12/3 16:42
 * @Description:
 */
@Service
@Slf4j
public class ImagesInfoServiceImpl implements ImagesInfoService{
    @Autowired
    ImagesInfoRepository imagesInfoRepository;
    @Autowired
    DockerComponent docker;
    @Autowired
    Sender sender;


    @Override
    public ImagesInfo SaveOrUpdate(ImagesInfo imagesInfo) {
        return imagesInfoRepository.save( imagesInfo );
    }

    @Override
    public ImagesInfo createNewImage(String imageId, String fullName, String name, String tag,
                                     String description, String instructions, Long size, Integer type,
                                     String authorName, Integer hasOpen, Long virtualSize, String labels,
                                     String cmd, String createDate, String updateDate) {
        ImagesInfo image = new ImagesInfo();
        image.setImageId( imageId );
        image.setFullName( fullName );
        image.setName( name );
        image.setTag( tag );
        image.setDescription( description );
        image.setInstructions( instructions );
        image.setSize( size );
        image.setType( type );
        image.setAuthorName( authorName );
        image.setHasOpen( hasOpen );
        image.setVirtualSize( virtualSize );
        image.setLabels( labels );
        image.setCmd( cmd );
        image.setCreateDate( createDate );
        image.setUpdateDate( updateDate );
        imagesInfoRepository.save( image );
        return image;
    }

    @Override
    public ImagesInfo findImagesInfoByFullName(String fullName) {
        return imagesInfoRepository.findOneByFullName( fullName );
    }

    @Async("taskExecutor")
    @Override
    public ImagesInfo createImageByImport(String fullName, InputStream stream,String description, String instructions, Integer type,
                                    String authorName, Integer hasOpen, String createDate, String updateDate ) throws DockerException, InterruptedException {
        //创建镜像
        docker.getThisDockerClient().create( fullName,stream );

        // 获取镜像的信息
        List<Image> list = docker.getThisDockerClient().listImages( DockerClient.ListImagesParam.byName(fullName));
        String imageId = list.get( 0 ).id().split( ":" )[1];

        ImageInfo imageInformation = docker.getThisDockerClient().inspectImage( imageId );
        //同步数据库
        ImagesInfo image_new_ =this.createNewImage( imageId,fullName,null,null,description,instructions,imageInformation.size(),
                type,authorName,hasOpen,imageInformation.virtualSize(),null,null,createDate,updateDate);
        if (image_new_==null) {
            return null;
        }
        return image_new_;
    }

    @Override
    public List<ImagesInfo> listAllImagesFromDataBase() {
        return imagesInfoRepository.findAll();
    }

    @Override
    public void deleteTheImage(String imageId) {
        ImagesInfo image = imagesInfoRepository.findOneByImageId( imageId );
        imagesInfoRepository.delete( image );
    }

    @Override
    public List<ImagesInfo> listImagesByHasOpen(Integer hasOpen) {
        List<ImagesInfo>list = imagesInfoRepository.findAllByHasOpen( hasOpen );
        return list;
    }

    @Override
    public Page<ImagesInfo> listImagesByHasOpenWithPage(Integer hasOpen, Integer pageIndex) {
        Pageable pageable = PageRequest.of( pageIndex,5);
        Page<ImagesInfo> page= imagesInfoRepository.findAllByHasOpen( hasOpen,pageable );
        return page;
    }

    @Override
    public List<ImagesInfo> listSelfImages(String authorName) {
        List<ImagesInfo> list = imagesInfoRepository.findAllByAuthorName( authorName );
        return list;
    }

    @Override
    public Page<ImagesInfo> listSelfImagesWithPage(String authorName, Integer pageIndex) {
        Pageable pageable = PageRequest.of( pageIndex,5);
        Page<ImagesInfo> page = imagesInfoRepository.findAllByAuthorName( authorName, pageable);
        return page;
    }

    @Override
    public ImmutableSet<String> listExportPorts(String imageId) {
        ImagesInfo image=imagesInfoRepository.findOneByImageId( imageId );
        String fullName = image.getFullName();
        try {
            ImageInfo info = docker.getThisDockerClient().inspectImage(fullName);
            return info.containerConfig().exposedPorts();
        } catch (Exception e) {
            log.error("获取镜像暴露端口错误，出错位置：{}，出错镜像ID：{}，错误信息：{}",
                    "ImagesInfoServiceImpl.listExportPorts()", imageId, e.getMessage());
            return null;
        }

    }

    @Async("taskExecutor")
    @Override
    public void imagePull(String fullName, String sessionId,String date) {

        MqTask mqTask = new MqTask();
        mqTask.setUid( sessionId );

        //拉去镜像
        try{
            docker.getThisDockerClient().pull( fullName );
        }catch (Exception e) {
            log.error("Pull Docker Hub镜像失败，错误位置：{}，镜像名：{}，错误栈：{}"
                    , "SysImageServiceImpl.imagePull()", fullName, e.getMessage());
            mqTask.setData( e.getMessage());
            sender.send( JsonUtils.objectToJson( mqTask  ));
            return;
        }

        //同步数据库
        try{
            List<Image> images = docker.getThisDockerClient().listImages(DockerClient.ListImagesParam.byName(fullName));
            if(images.size() <= 0) {
                mqTask.setData("本地没有拉取下来指定镜像");
                sender.send( JsonUtils.objectToJson( mqTask  ));
                return;
            }
            // 获取镜像的id
            String imageId = images.get( 0 ).id().split( ":" )[1];
            ImageInfo imageInformation = docker.getThisDockerClient().inspectImage( imageId );
            //同步数据库
            ImagesInfo image_new_ =this.createNewImage( imageId,fullName,null,null,null,null,imageInformation.size(),
                    1,"public",1,imageInformation.virtualSize(),null,null,date,date);
            if (image_new_==null) {
                mqTask.setData("同步数据库出现异常");
                sender.send( JsonUtils.objectToJson( mqTask  ));
                return;
            }
            mqTask.setData("本地成功拉取下来指定镜像！");
            sender.send( JsonUtils.objectToJson( mqTask  ));
            return;

        }catch (Exception e1) {
            mqTask.setData(e1.getMessage());
            sender.send( JsonUtils.objectToJson( mqTask  ));
            return;
        }

    }

    @Async("taskExecutor")
    @Override
    public void task1() {

        System.out.println( "task1:" );

    }
    @Async("taskExecutor")
    @Override
    public void task2() throws InterruptedException {
        Thread.sleep( 1000 );
        System.out.println( "task2:" );
    }
    @Async("taskExecutor")
    @Override
    public void task3() {
        System.out.println( "task3:" );
    }
}
